package com.examlpe.lotterysystem.service.activitystatus.impl;

import com.examlpe.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.examlpe.lotterysystem.common.exception.ServiceException;
import com.examlpe.lotterysystem.service.ActivityService;
import com.examlpe.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.examlpe.lotterysystem.service.activitystatus.operater.AbstractActivityOperater;
import com.examlpe.lotterysystem.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Component
public class ActivityStatusManagerImpl implements ActivityStatusManager{

    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManager.class);

    @Autowired
    private Map<String, AbstractActivityOperater> operaterMap = new HashMap<>();
    @Autowired
    private ActivityService activityService;
    /**
     * 处理活动相关状态转换
     * @param convertActivityStatusDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //活动状态扭转有依赖性,导致代码维护性差
        //状态扭转条件可能会拓展
        if(CollectionUtils.isEmpty(operaterMap)) {
            logger.warn("operaterMap 为空");
        }
        //map<String,AbstractActivityOperater>
        Map<String,AbstractActivityOperater> currMap = new HashMap<>(operaterMap);
        Boolean update = false;
        ///1.先处理 人员  奖品
        update = processConvertStatus(convertActivityStatusDTO,currMap,1);
        //2.后处理  活动
        update = processConvertStatus(convertActivityStatusDTO,currMap,2) || update;
        //更新缓存
        if(update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    /*处理回滚活动扭转*/
    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //operaterMap：活动，奖品，人员回滚
        //活动必选回滚
        for(AbstractActivityOperater operater : operaterMap.values()) {
            operater.convert(convertActivityStatusDTO);
        }
        //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperater> currMap,
                                         int sequence) {
        Boolean update = false;
        //遍历currMap
        Iterator<Map.Entry<String,AbstractActivityOperater>> iterator = currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperater operater = iterator.next().getValue();
            //Operater是否需要转换
            if(operater.sequence() != sequence
                    || !operater.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            //需要转换:转换
            if(!operater.convert(convertActivityStatusDTO)) {
                logger.warn("{}状态转换失败！",operater.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_ERROR);
            }
            //currMap,删除当前Operater
            iterator.remove();
            update = true;
        }
        //返回
        return update;
    }
}
